package br.ufal.ic.ptl.syntaticanalyzer.lexer;

import junit.framework.TestCase;

public class ScannerTest extends TestCase {

	protected void setUp() throws Exception {
		super.setUp();
	}

	protected void tearDown() throws Exception {
		super.tearDown();
	}

	public void testScan() {
		Scanner sc = getScannerFromFile("C:\\simples.txt");
		assertEquals(TokenType.IDENTIFIER, sc.scan().getKind());
		assertEquals(TokenType.LPAREN, sc.scan().getKind());
		assertEquals(TokenType.RPAREN, sc.scan().getKind());
		assertEquals(TokenType.LBRACKET, sc.scan().getKind());
		assertEquals(TokenType.RBRACKET, sc.scan().getKind());
	}

	public void testCharLiteral() {
		Scanner sc = getScannerFromFile("C:\\charliteral.txt");
		Token t = sc.scan();
		assertEquals(TokenType.CHARLITERAL, t.getKind());
		assertEquals("'Copacabana'", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.CHARLITERAL, t.getKind());
		assertEquals("''", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.CHARLITERAL, t.getKind());
		assertEquals("'Ca123bana'", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.ERROR, t.getKind());

	}

	public void testIdentifiersWithOperators() {
		Scanner sc = getScannerFromFile("C:\\identifiers.txt");
		Token t = sc.scan();
		assertEquals(TokenType.IDENTIFIER, t.getKind());
		assertEquals("e_mola", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.IDENTIFIER, t.getKind());
		assertEquals("E123", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.IDENTIFIER, t.getKind());
		assertEquals("e123", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.IDENTIFIER, t.getKind());
		assertEquals("e", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.MULT, t.getKind());
		assertEquals("*", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.INTLITERAL, t.getKind());
		assertEquals("123", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.MULT, t.getKind());
		assertEquals("*", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.IDENTIFIER, t.getKind());
		assertEquals("m_456", t.getSpell());
	}

	public void testReservedWords() {
		Scanner sc = getScannerFromFile("C:\\reserved.txt");
		Token t = sc.scan();
		assertEquals(TokenType.BEGIN, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.END, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.ACTIVITY, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.SEND_INFORMATION, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.CHAT, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.REUSE, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.THEN, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.VAR, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.WHILE, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.WRITE, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.READ, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.IF, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.ELSE, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.ENDIF, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.AND, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.OR, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.TRUE, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.FALSE, t.getKind());
	}

	public void testPunctuationSpecialSymbolsAndBrackets() {
		Scanner sc = getScannerFromFile("C:\\symbols.txt");
		Token t = sc.scan();
		assertEquals(TokenType.COMMA, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.SEMICOLON, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.COLON, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.ATTRIB, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.RCURLY, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.LCURLY, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.RPAREN, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.LPAREN, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.RBRACKET, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.LBRACKET, t.getKind());
	}

	public void testOperators() {
		Scanner sc = getScannerFromFile("C:\\operators.txt");
		Token t = sc.scan();
		assertEquals(TokenType.MULT, t.getKind());
		assertEquals("*", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.DIV, t.getKind());
		assertEquals("/", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.PLUS, t.getKind());
		assertEquals("+", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.MINUS, t.getKind());
		assertEquals("-", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.LOETHAN, t.getKind());
		assertEquals("<=", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.ATTRIB, t.getKind());
		assertEquals("=", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.DIFFERENT, t.getKind());
		assertEquals("<>", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.GOETHAN, t.getKind());
		assertEquals(">=", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.EQUALS, t.getKind());
		assertEquals("==", t.getSpell());
		t = sc.scan();
		assertEquals(TokenType.ATTRIB, t.getKind());
		assertEquals("=", t.getSpell());
	}

	public void testComments() {
		Scanner sc = getScannerFromFile("C:\\comments.txt");
		Token t = sc.scan();
		assertEquals(TokenType.BEGIN, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.END, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.END, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.LCURLY, t.getKind());
		t = sc.scan();
		assertEquals(TokenType.RCURLY, t.getKind());
	}

	public void testLines() {
		Scanner source = getScannerFromFile("C:\\Documents and Settings\\Fritz.MANAGER\\workspace"
				+ "\\PTL\\tests\\br\\"
				+ "ufal\\ic\\ptl\\syntaticanalyzer\\parser"
				+ "\\sourcesamples\\brokenline");
		Token t = source.scan();
		assertEquals(1, t.getPosition().getFinish());
		t = source.scan();
		assertEquals(3, t.getPosition().getFinish());
		t = source.scan();
		assertEquals(5, t.getPosition().getFinish());
		t = source.scan();
		assertEquals(8, t.getPosition().getFinish());
		t = source.scan();
		assertEquals(9, t.getPosition().getFinish());
		t = source.scan();
		assertEquals(10, t.getPosition().getStart());
		t = source.scan();
		assertEquals(15, t.getPosition().getFinish());
	}

	private Scanner getScannerFromFile(String fileName) {
		SourceFile sourceFile = new SourceFile(fileName);
		return new Scanner(sourceFile);
	}

}
